home *** CD-ROM | disk | FTP | other *** search
-
- #include "lib_init.h"
- #include "lib_debug.h"
- #include <render/render.h>
- #include <proto/utility.h>
- #include <proto/exec.h>
- #include <graphics/gfx.h>
-
- #define NUMRAND 1237 /* prime number */
-
- static LONG getrand(LONG seed)
- {
- ULONG lo, hi;
-
- lo = 16807 * (LONG) (seed & 0xffff);
- hi = 16807 * (LONG) ((ULONG) seed >> 16);
- lo += (hi & 0x7fff) << 16;
- if (lo > 2147483647)
- {
- lo &= 2147483647;
- ++lo;
- }
- lo += hi >> 15;
- if (lo > 2147483647)
- {
- lo &= 2147483647;
- ++lo;
- }
-
- return (LONG) lo;
- }
-
- /**************************************************************************
- **
- ** callbacks for rendering
- **
- **************************************************************************/
-
- /*
- ** floyd: P A=7
- ** B=3 C=5 D=1
- */
-
- static __inline UBYTE dither_floyd(struct RenderData *rnd, WORD *dithbuf, WORD r, WORD g, WORD b)
- {
- ULONG rgb;
- UBYTE pen;
- WORD A, B;
-
- r += rnd->Ar;
- g += rnd->Ag;
- b += rnd->Ab;
-
- if (r < 0) r = 0; else if (r > 255) r = 255;
- if (g < 0) g = 0; else if (g > 255) g = 255;
- if (b < 0) b = 0; else if (b > 255) b = 255;
-
- pen = P2Lookup2(rnd->dstpal, r, g, b);
- rgb = rnd->dstpal->table[pen];
-
- b -= rgb & 0xff;
- rgb >>= 8;
- g -= rgb & 0xff;
- rgb >>= 8;
- r -= rgb & 0xff;
-
- B = r + r;
- A = (B + r) >> 4;
- dithbuf[0] = rnd->Br + A;
- B = (B + B + r) >> 4;
- A += B;
- rnd->Br = rnd->Cr + B;
- B = r >> 4;
- rnd->Cr = B;
- rnd->Ar = r - A - B;
-
- B = g + g;
- A = (B + g) >> 4;
- dithbuf[1] = rnd->Bg + A;
- B = (B + B + g) >> 4;
- A += B;
- rnd->Bg = rnd->Cg + B;
- B = g >> 4;
- rnd->Cg = B;
- rnd->Ag = g - A - B;
-
- B = b + b;
- A = (B + b) >> 4;
- dithbuf[2] = rnd->Bb + A;
- B = (B + B + b) >> 4;
- A += B;
- rnd->Bb = rnd->Cb + B;
- B = b >> 4;
- rnd->Cb = B;
- rnd->Ab = b - A - B;
-
- return pen;
- }
-
- /**************************************************************************
- ** renderx: rgb dither floyd
- */
-
- static void renderx_rgb_dither_floyd(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- WORD *dithbuf = rnd->ditherbuf + 3;
- ULONG rgb;
- WORD r, g, b;
-
- rnd->Br = 0;
- rnd->Cr = 0;
- rnd->Ar = 0;
- rnd->Bg = 0;
- rnd->Cg = 0;
- rnd->Ag = 0;
- rnd->Bb = 0;
- rnd->Cb = 0;
- rnd->Ab = 0;
-
- if (rnd->flipflop ^= 1)
- {
- while (width--)
- {
- rgb = *src++;
- r = *dithbuf++ + ((rgb & 0xff0000) >> 16);
- g = *dithbuf++ + ((rgb & 0x00ff00) >> 8);
- b = *dithbuf++ + (rgb & 0x0000ff);
- *dst++ = rnd->pentab[dither_floyd(rnd, dithbuf - 3, r, g, b)];
- }
- }
- else
- {
- src += width;
- dst += width;
- dithbuf += width * 3;
- while (width--)
- {
- rgb = *--src;
- b = *--dithbuf + (rgb & 0x0000ff);
- g = *--dithbuf + ((rgb & 0x00ff00) >> 8);
- r = *--dithbuf + ((rgb & 0xff0000) >> 16);
- *--dst = rnd->pentab[dither_floyd(rnd, dithbuf + 3, r, g, b)];
- }
- }
- }
-
-
- /**************************************************************************
- ** renderx: chunky dither floyd
- */
-
- static void renderx_chunky_dither_floyd(struct RenderData *rnd, UBYTE *src, UBYTE *dst, LONG width)
- {
- RNDPAL *srcpal = rnd->srcpal;
- WORD *dithbuf = rnd->ditherbuf + 3;
- ULONG rgb;
- WORD r, g, b;
-
- rnd->Br = 0;
- rnd->Cr = 0;
- rnd->Ar = 0;
- rnd->Bg = 0;
- rnd->Cg = 0;
- rnd->Ag = 0;
- rnd->Bb = 0;
- rnd->Cb = 0;
- rnd->Ab = 0;
-
- if (rnd->flipflop ^= 1)
- {
- while (width--)
- {
- rgb = srcpal->table[*src++];
- r = *dithbuf++ + ((rgb & 0xff0000) >> 16);
- g = *dithbuf++ + ((rgb & 0x00ff00) >> 8);
- b = *dithbuf++ + (rgb & 0x0000ff);
- *dst++ = rnd->pentab[dither_floyd(rnd, dithbuf - 3, r, g, b)];
- }
- }
- else
- {
- src += width;
- dst += width;
- dithbuf += width * 3;
- while (width--)
- {
- rgb = srcpal->table[*--src];
- b = *--dithbuf + (rgb & 0x0000ff);
- g = *--dithbuf + ((rgb & 0x00ff00) >> 8);
- r = *--dithbuf + ((rgb & 0xff0000) >> 16);
- *--dst = rnd->pentab[dither_floyd(rnd, dithbuf + 3, r, g, b)];
- }
- }
- }
-
-
- /*
- ** edd: P A=1
- ** B=1
- */
-
- #define dither_edd(rgb) \
- r += dithbuf[0]; \
- g += dithbuf[1]; \
- b += dithbuf[2]; \
- b += rgb & 0xff; \
- rgb >>= 8; \
- g += rgb & 0xff; \
- rgb >>= 8; \
- r += rgb & 0xff; \
- if (r < 0) r = 0; else if (r > 255) r = 255; \
- if (g < 0) g = 0; else if (g > 255) g = 255; \
- if (b < 0) b = 0; else if (b > 255) b = 255; \
- rgb = r; \
- rgb <<= 8; \
- rgb |= g; \
- rgb <<= 8; \
- rgb |= b; \
- pen = P2Lookup(dstpal, rgb); \
- rgb = dstpal->table[pen]; \
- r -= (rgb & 0xff0000) >> 16; \
- g -= (rgb & 0x00ff00) >> 8; \
- b -= (rgb & 0x0000ff); \
- r -= dithbuf[0] = r >> 1; \
- g -= dithbuf[1] = g >> 1; \
- b -= dithbuf[2] = b >> 1;
-
-
- /**************************************************************************
- ** renderx: rgb dither EDD
- */
-
- static void renderx_rgb_dither_edd(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *dstpal = rnd->dstpal;
- WORD *dithbuf = rnd->ditherbuf;
- ULONG rgb;
- WORD r = 0, g = 0, b = 0;
- UBYTE pen;
-
- if (rnd->flipflop ^= 1)
- {
- while (width--)
- {
- rgb = *src++;
- dither_edd(rgb);
- *dst++ = pentab[pen];
- dithbuf += 3;
- }
- }
- else
- {
- src += width;
- dst += width;
- dithbuf += width * 3;
- while (width--)
- {
- dithbuf -= 3;
- rgb = *--src;
- dither_edd(rgb);
- *--dst = pentab[pen];
- }
- }
- }
-
-
- /**************************************************************************
- ** renderx: chunky dither EDD
- */
-
- static void renderx_chunky_dither_edd(struct RenderData *rnd, UBYTE *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *srcpal = rnd->srcpal;
- RNDPAL *dstpal = rnd->dstpal;
- WORD *dithbuf = rnd->ditherbuf;
- ULONG rgb;
- WORD r = 0, g = 0, b = 0;
- UBYTE pen;
-
- if (rnd->flipflop ^= 1)
- {
- while (width--)
- {
- rgb = srcpal->table[*src++];
- dither_edd(rgb);
- *dst++ = pentab[pen];
- dithbuf += 3;
- }
- }
- else
- {
- src += width;
- dst += width;
- dithbuf += width * 3;
- while (width--)
- {
- dithbuf -= 3;
- rgb = srcpal->table[*--src];
- dither_edd(rgb);
- *--dst = pentab[pen];
- }
- }
- }
-
-
-
- /*
- ** random dither
- */
-
- #define dither_random(rgb) \
- b += rgb & 0xff; \
- rgb >>= 8; \
- g += rgb & 0xff; \
- rgb >>= 8; \
- r += rgb & 0xff; \
- if (r < 0) r = 0; else if (r > 255) r = 255; \
- if (g < 0) g = 0; else if (g > 255) g = 255; \
- if (b < 0) b = 0; else if (b > 255) b = 255; \
- rgb = r; \
- rgb <<= 8; \
- rgb |= g; \
- rgb <<= 8; \
- rgb |= b; \
- pen = P2Lookup(dstpal, rgb); \
- rgb = dstpal->table[pen]; \
- b -= rgb & 0xff; \
- rgb >>= 8; \
- g -= rgb & 0xff; \
- rgb >>= 8; \
- r -= rgb & 0xff; \
- if (--randi < 0) randi = NUMRAND - 1; \
- r += rnd->randtab[randi]; \
- if (--randi < 0) randi = NUMRAND - 1; \
- g += rnd->randtab[randi]; \
- if (--randi < 0) randi = NUMRAND - 1; \
- b += rnd->randtab[randi];
-
-
- /**************************************************************************
- ** renderx: rgb dither random
- */
-
- static void renderx_rgb_dither_rand(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *dstpal = rnd->dstpal;
- WORD *dithbuf = rnd->ditherbuf;
- ULONG rgb;
- WORD r = 0, g = 0, b = 0;
- UBYTE pen;
- WORD randi = rnd->randi;
-
- if (rnd->flipflop ^= 1)
- {
- while (width--)
- {
- rgb = *src++;
- dither_random(rgb);
- *dst++ = pentab[pen];
- dithbuf += 3;
- }
- }
- else
- {
- src += width;
- dst += width;
- dithbuf += width * 3;
- while (width--)
- {
- dithbuf -= 3;
- rgb = *--src;
- dither_random(rgb);
- *--dst = pentab[pen];
- }
- }
-
- rnd->randi = randi;
- }
-
-
- /**************************************************************************
- ** renderx: chunky dither random
- */
-
- static void renderx_chunky_dither_rand(struct RenderData *rnd, UBYTE *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *srcpal = rnd->srcpal;
- RNDPAL *dstpal = rnd->dstpal;
- WORD *dithbuf = rnd->ditherbuf;
- ULONG rgb;
- WORD r = 0, g = 0, b = 0;
- UBYTE pen;
- WORD randi = rnd->randi;
-
- if (rnd->flipflop ^= 1)
- {
- while (width--)
- {
- rgb = srcpal->table[*src++];
- dither_random(rgb);
- *dst++ = pentab[pen];
- dithbuf += 3;
- }
- }
- else
- {
- src += width;
- dst += width;
- dithbuf += width * 3;
- while (width--)
- {
- dithbuf -= 3;
- rgb = srcpal->table[*--src];
- dither_random(rgb);
- *--dst = pentab[pen];
- }
- }
-
- rnd->randi = randi;
- }
-
-
-
-
- /**************************************************************************
- ** renderx: rgb plain
- */
-
- static void renderx_rgb_plain(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- RNDPAL *dstpal = rnd->dstpal;
- while (width--)
- {
- *dst++ = P2Lookup(dstpal, *src++);
- }
- }
-
- /**************************************************************************
- ** renderx: rgb with pentab
- */
-
- static void renderx_rgb_pentab(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *dstpal = rnd->dstpal;
- while (width--)
- {
- *dst++ = pentab[P2Lookup(dstpal, *src++)];
- }
- }
-
-
-
- #define lookupham6(rgb,r,g,b) \
- { LONG nr, ng, nb, d, bestd; ULONG rgb2; UBYTE p2; \
- nr = (rgb & 0xf00000) >> 20; \
- ng = (rgb & 0x00f000) >> 12; \
- nb = (rgb & 0x0000f0) >> 4; \
- bestd = (ng-g)*(ng-g) + (nb-b)*(nb-b); \
- pen = 0x20 | nr; \
- rgb2 = (nr << 8) | (g << 4) | b; \
- d = (nr-r)*(nr-r) + (nb-b)*(nb-b); \
- if (d < bestd) \
- { \
- bestd = d; \
- pen = 0x30 | ng; \
- rgb2 = (r << 8) | (ng << 4) | b; \
- } \
- d = (nr-r)*(nr-r) + (ng-g)*(ng-g); \
- if (d < bestd) \
- { \
- bestd = d; \
- pen = 0x10 | nb; \
- rgb2 = (r << 8) | (g << 4) | nb; \
- } \
- p2 = P2Lookup(dstpal, rgb); \
- rgb = dstpal->table[p2]; \
- r = (rgb & 0xf00000) >> 20; \
- g = (rgb & 0x00f000) >> 12; \
- b = (rgb & 0x0000f0) >> 4; \
- nr -= r; \
- ng -= g; \
- nb -= b; \
- if (nr*nr + ng*ng + nb*nb < bestd) \
- { \
- pen = pentab[p2]; \
- } \
- else \
- { \
- r = (rgb2 & 0xf00) >> 8; \
- g = (rgb2 & 0x0f0) >> 4; \
- b = (rgb2 & 0x00f); \
- } \
- }
-
- /**************************************************************************
- ** renderx: rgb to ham6
- */
-
- static void renderx_rgb_ham6(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *dstpal = rnd->dstpal;
-
- LONG hr = (dstpal->table[0] & 0xf00000) >> 20;
- LONG hg = (dstpal->table[0] & 0x00f000) >> 12;
- LONG hb = (dstpal->table[0] & 0x0000f0) >> 4;
- ULONG rgb;
- UBYTE pen;
-
- while (width--)
- {
- rgb = *src++;
- lookupham6(rgb, hr,hg,hb);
- *dst++ = pen;
- }
- }
-
- /**************************************************************************
- ** renderx: chunky to ham6
- */
-
- static void renderx_chunky_ham6(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *srcpal = rnd->srcpal;
- RNDPAL *dstpal = rnd->dstpal;
-
- LONG hr = (dstpal->table[0] & 0xf00000) >> 20;
- LONG hg = (dstpal->table[0] & 0x00f000) >> 12;
- LONG hb = (dstpal->table[0] & 0x0000f0) >> 4;
- ULONG rgb;
- UBYTE pen;
-
- while (width--)
- {
- rgb = srcpal->table[*src++];
- lookupham6(rgb, hr,hg,hb);
- *dst++ = pen;
- }
- }
-
-
-
-
- #define lookupham8(rgb,r,g,b) \
- { LONG nr, ng, nb, d, bestd; ULONG rgb2; UBYTE p2; \
- nr = (r & 3) | ((rgb & 0xfc0000) >> 16); \
- ng = (g & 3) | ((rgb & 0x00fc00) >> 8); \
- nb = (b & 3) | (rgb & 0x0000fc); \
- bestd = (ng-g)*(ng-g) + (nb-b)*(nb-b); \
- pen = 0x80 | (nr>>2); \
- rgb2 = (nr << 16) | (g << 8) | b; \
- d = (nr-r)*(nr-r) + (nb-b)*(nb-b); \
- if (d < bestd) \
- { \
- bestd = d; \
- pen = 0xc0 | (ng>>2); \
- rgb2 = (r << 16) | (ng << 8) | b; \
- } \
- d = (nr-r)*(nr-r) + (ng-g)*(ng-g); \
- if (d < bestd) \
- { \
- bestd = d; \
- pen = 0x40 | (nb>>2); \
- rgb2 = (r << 16) | (g << 8) | nb; \
- } \
- p2 = P2Lookup(dstpal, rgb); \
- rgb = dstpal->table[p2]; \
- r = (rgb & 0xff0000) >> 16; \
- g = (rgb & 0x00ff00) >> 8; \
- b = (rgb & 0x0000ff); \
- nr -= r; \
- ng -= g; \
- nb -= b; \
- if (nr*nr + ng*ng + nb*nb < bestd) \
- { \
- pen = pentab[p2]; \
- } \
- else \
- { \
- r = (rgb2 & 0xff0000) >> 16; \
- g = (rgb2 & 0x00ff00) >> 8; \
- b = (rgb2 & 0x0000ff); \
- } \
- }
-
- /**************************************************************************
- ** renderx: rgb to ham8
- */
-
- static void renderx_rgb_ham8(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *dstpal = rnd->dstpal;
-
- LONG hr = (dstpal->table[0] & 0xff0000) >> 16;
- LONG hg = (dstpal->table[0] & 0x00ff00) >> 8;
- LONG hb = (dstpal->table[0] & 0x0000ff);
- ULONG rgb;
- UBYTE pen;
-
- while (width--)
- {
- rgb = *src++;
- lookupham8(rgb, hr,hg,hb);
- *dst++ = pen;
- }
- }
-
- /**************************************************************************
- ** renderx: chunky to ham8
- */
-
- static void renderx_chunky_ham8(struct RenderData *rnd, ULONG *src, UBYTE *dst, LONG width)
- {
- UBYTE *pentab = rnd->pentab;
- RNDPAL *srcpal = rnd->srcpal;
- RNDPAL *dstpal = rnd->dstpal;
-
- LONG hr = (dstpal->table[0] & 0xff0000) >> 16;
- LONG hg = (dstpal->table[0] & 0x00ff00) >> 8;
- LONG hb = (dstpal->table[0] & 0x0000ff);
- ULONG rgb;
- UBYTE pen;
-
- while (width--)
- {
- rgb = srcpal->table[*src++];
- lookupham8(rgb, hr,hg,hb);
- *dst++ = pen;
- }
- }
-
-
-
-
- /**************************************************************************
- ** renderx: chunky plain
- */
-
- static void renderx_chunky_plain(struct RenderData *rnd, UBYTE *src, UBYTE *dst, LONG width)
- {
- RNDPAL *srcpal = rnd->srcpal;
- RNDPAL *dstpal = rnd->dstpal;
- while (width--)
- {
- *dst++ = P2Lookup(dstpal, srcpal->table[*src++]);
- }
- }
-
- /**************************************************************************
- ** renderx: chunky with pentab
- */
-
- static void renderx_chunky_pentab(struct RenderData *rnd, UBYTE *src, UBYTE *dst, LONG width)
- {
- RNDPAL *srcpal = rnd->srcpal;
- RNDPAL *dstpal = rnd->dstpal;
- UBYTE *pentab = rnd->pentab;
- while (width--)
- {
- *dst++ = pentab[P2Lookup(dstpal, srcpal->table[*src++])];
- }
- }
-
-
-
-
- /**************************************************************************
- ** rendery: plain with hooks
- */
-
- static ULONG rendery_plain_hooks(struct RenderData *rnd)
- {
- ULONG result = REND_CALLBACK_ABORTED;
- UBYTE *src = rnd->src;
- UBYTE *dst = rnd->dst;
- LONG y;
-
- for (y = 0; y < rnd->height; ++y)
- {
- if (rnd->linehook)
- {
- rnd->fetchmsg.RND_LMsg_row = y;
- if (!CallHookPkt(rnd->linehook, src, &rnd->fetchmsg)) goto abort;
- }
-
- (*rnd->renderxfunc)(rnd, src, dst, rnd->width);
-
- if (rnd->linehook)
- {
- rnd->rendermsg.RND_LMsg_row = y;
- if (!CallHookPkt(rnd->linehook, dst, &rnd->rendermsg)) goto abort;
- }
-
- if (rnd->proghook)
- {
- rnd->progmsg.RND_PMsg_count = y;
- if (!CallHookPkt(rnd->proghook, rnd->dstpal, &rnd->progmsg)) goto abort;
- }
-
- src += rnd->tsw * rnd->srcbpp;
- dst += rnd->tdw * rnd->dstbpp;
- }
-
- result = REND_SUCCESS;
-
- abort:
- return result;
- }
-
-
- /**************************************************************************
- ** rendery: with scale-engine and hooks
- */
-
- static ULONG rendery_scale_hooks(struct RenderData *rnd)
- {
- ULONG result = REND_NOT_ENOUGH_MEMORY;
- APTR linebuf;
-
- linebuf = AllocRenderMem(rnd->rmh, rnd->scaleengine->dw * rnd->srcbpp);
- if (linebuf)
- {
- if ((*rnd->scaleengine->initfunc)(rnd->scaleengine, &rnd->scdata))
- {
- UBYTE *dst = rnd->dst;
- LONG y;
-
- result = REND_CALLBACK_ABORTED;
-
- for (y = 0; y < rnd->scaleengine->dh; ++y)
- {
- UBYTE *src = rnd->src;
-
- if (rnd->bgcolor != 0xffffffff)
- {
- memfill32(linebuf, rnd->scaleengine->dw * rnd->srcbpp, rnd->bgcolor);
- }
- else if (rnd->bgpen != 0xffffffff)
- {
- memfill8(linebuf, rnd->scaleengine->dw * rnd->srcbpp, rnd->bgpen);
- }
-
- (*rnd->scaleengine->scalefunc)(rnd->scaleengine, &rnd->scdata, src, linebuf, y, rnd->tsw);
- (*rnd->renderxfunc)(rnd, linebuf, dst, rnd->scaleengine->dw);
-
- if (rnd->linehook)
- {
- rnd->rendermsg.RND_LMsg_row = y;
- if (!CallHookPkt(rnd->linehook, dst, &rnd->rendermsg)) goto abort;
- }
-
- if (rnd->proghook)
- {
- rnd->progmsg.RND_PMsg_count = y;
- if (!CallHookPkt(rnd->proghook, rnd->dstpal, &rnd->progmsg)) goto abort;
- }
-
- dst += rnd->tdw * rnd->dstbpp;
- }
-
- result = REND_SUCCESS;
- abort:
- (*rnd->scaleengine->exitfunc)(rnd->scaleengine, &rnd->scdata);
- }
- FreeRenderMem(rnd->rmh, linebuf, rnd->scaleengine->dw * rnd->srcbpp);
- }
-
- return result;
- }
-
-
-
- /**************************************************************************
- ** init render data.
- ** dstpal, width, height, src, dst, srcpal, srcbpp
- ** must be initialized by the caller.
- */
-
- static ULONG initrender(struct RenderData *rnd, struct TagItem *tags)
- {
- LONG colormode = GetTagData(RND_ColorMode, COLORMODE_CLUT, tags);
-
- if (!rnd->dstpal) return REND_NO_DATA;
- if (!GetP2Table(rnd->dstpal)) return REND_NOT_ENOUGH_MEMORY;
-
- rnd->rmh = rnd->dstpal->rmh;
- rnd->dstbpp = 1;
-
- rnd->tsw = GetTagData(RND_SourceWidth, rnd->width, tags);
- rnd->tdw = GetTagData(RND_DestWidth, rnd->width, tags);
-
- rnd->pentab = (UBYTE *) GetTagData(RND_PenTable, NULL, tags);
- if (!rnd->pentab)
- {
- LONG oz = GetTagData(RND_OffsetColorZero, 0, tags);
-
- LONG i;
- for (i = 0; i < 256; ++i)
- {
- rnd->pens[i] = i + oz;
- }
-
- if (oz)
- {
- rnd->pentab = rnd->pens;
- }
- }
-
- rnd->proghook = (struct Hook *) GetTagData(RND_ProgressHook, NULL, tags);
- rnd->linehook = (struct Hook *) GetTagData(RND_LineHook, NULL, tags);
-
- rnd->fetchmsg.RND_LMsg_type = LMSGTYPE_LINE_FETCH;
- rnd->rendermsg.RND_LMsg_type = LMSGTYPE_LINE_RENDERED;
- rnd->progmsg.RND_PMsg_type = PMSGTYPE_LINES_RENDERED;
- rnd->progmsg.RND_PMsg_total = rnd->height;
-
- rnd->scaleengine = (struct ScaleEngine *) GetTagData(RND_ScaleEngine, NULL, tags);
- if (rnd->scaleengine)
- {
- /* override */
- rnd->width = rnd->scaleengine->dw;
- rnd->height = rnd->scaleengine->dh;
-
- rnd->bgcolor = GetTagData(RND_BGColor, 0xffffffff, tags);
- rnd->bgpen = GetTagData(RND_BGPen, 0xffffffff, tags);
- }
-
-
- rnd->dithermode = GetTagData(RND_DitherMode, DITHERMODE_NONE, tags);
- if (rnd->dithermode != DITHERMODE_NONE)
- {
- rnd->ditherbuf = AllocRenderVecClear(rnd->rmh, sizeof(UWORD) * 3 * (rnd->width + 2));
- if (!rnd->ditherbuf) return REND_NOT_ENOUGH_MEMORY;
- if (rnd->dithermode == DITHERMODE_RANDOM)
- {
- LONG i, seed;
- LONG amount = GetTagData(RND_DitherAmount, 128, tags);
- rnd->randtab = AllocRenderMem(rnd->rmh, NUMRAND);
- if (!rnd->randtab) return REND_NOT_ENOUGH_MEMORY;
- for (i = 0; i < NUMRAND; ++i)
- {
- rnd->randtab[i] = (seed = getrand(seed)) % amount - amount/2;
- }
- }
- }
-
-
- /* determine renderx function */
- if (rnd->srcbpp == 1)
- {
- switch (colormode)
- {
- case COLORMODE_CLUT:
- switch (rnd->dithermode)
- {
- case DITHERMODE_EDD:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_dither_edd;
- break;
- case DITHERMODE_FS:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_dither_floyd;
- break;
- case DITHERMODE_RANDOM:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_dither_rand;
- break;
-
- default:
- case DITHERMODE_NONE:
- if (rnd->pentab)
- {
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_pentab;
- }
- else
- {
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_plain;
- }
- break;
- }
- break;
-
- case COLORMODE_HAM6:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_ham6;
- break;
-
- case COLORMODE_HAM8:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_chunky_ham8;
- break;
- }
- }
- else if (rnd->srcbpp == 4)
- {
- switch (colormode)
- {
- case COLORMODE_CLUT:
- switch (rnd->dithermode)
- {
- case DITHERMODE_EDD:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_dither_edd;
- break;
- case DITHERMODE_FS:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_dither_floyd;
- break;
- case DITHERMODE_RANDOM:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_dither_rand;
- break;
-
- default:
- case DITHERMODE_NONE:
- if (rnd->pentab)
- {
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_pentab;
- }
- else
- {
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_plain;
- }
- break;
- }
- break;
-
- case COLORMODE_HAM6:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_ham6;
- break;
-
- case COLORMODE_HAM8:
- rnd->renderxfunc = (void (*)(struct RenderData *, APTR, APTR, LONG)) renderx_rgb_ham8;
- break;
- }
- }
-
- /* determine rendery function */
- if (rnd->scaleengine)
- {
- rnd->renderyfunc = (ULONG (*)(struct RenderData *data)) rendery_scale_hooks;
- }
- else
- {
- rnd->renderyfunc = (ULONG (*)(struct RenderData *data)) rendery_plain_hooks;
- }
-
-
- if (!rnd->pentab) rnd->pentab = rnd->pens;
-
- return REND_SUCCESS;
- }
-
-
- static void exitrender(struct RenderData *data)
- {
- if (data->randtab) FreeRenderMem(data->rmh, data->randtab, NUMRAND);
- FreeRenderVec((ULONG *) data->ditherbuf);
- }
-
-
- /**************************************************************************
- **
- ** render
- */
-
- LIBAPI ULONG RenderA(ULONG *src, UWORD w, UWORD h, UBYTE *dst, RNDPAL *dstpal, struct TagItem *tags)
- {
- ULONG result = REND_NO_DATA;
-
- if (src && dst && w && h && dstpal)
- {
- struct RenderData data;
- memfill8((UBYTE *) &data, sizeof(struct RenderData), 0);
-
- ObtainSemaphore(&dstpal->lock);
-
- data.src = src;
- data.srcbpp = 4;
- data.dst = dst;
- data.width = w;
- data.height = h;
- data.dstpal = dstpal;
- result = initrender(&data, tags);
- if (result == REND_SUCCESS)
- {
- result = (*data.renderyfunc)(&data);
- }
- exitrender(&data);
-
- ReleaseSemaphore(&dstpal->lock);
- }
-
- return result;
- }
-
-
- /**************************************************************************
- **
- ** convertchunky
- */
-
- LIBAPI ULONG ConvertChunkyA(UBYTE *src, RNDPAL *srcpal, UWORD w, UWORD h, UBYTE *dst, RNDPAL *dstpal, struct TagItem *tags)
- {
- ULONG result = REND_NO_DATA;
-
- if (src && dst && w && h && dstpal)
- {
- struct RenderData data;
- memfill8((UBYTE *) &data, sizeof(struct RenderData), 0);
-
- ObtainSemaphore(&dstpal->lock);
- ObtainSemaphoreShared(&srcpal->lock);
-
- data.src = src;
- data.srcpal = srcpal;
- data.srcbpp = 1;
- data.dst = dst;
- data.dstpal = dstpal;
- data.width = w;
- data.height = h;
- result = initrender(&data, tags);
- if (result == REND_SUCCESS)
- {
- result = (*data.renderyfunc)(&data);
- }
- exitrender(&data);
-
- ReleaseSemaphore(&srcpal->lock);
- ReleaseSemaphore(&dstpal->lock);
- }
-
- return result;
- }
-